﻿using ActUtlType64Lib;
namespace ProgramLogicControl
{
    public sealed class Mitsubishi : PLCBase
    {
        private static readonly Mitsubishi instance = new Mitsubishi();

       // private static object syncRoot = new object();
        
        private bool isopen;
        private bool state;
        private string lastmessage;
        /// <summary>
        /// 链接状态
        /// </summary>
        public bool IsOpen {  get { return isopen; } }

        public bool State {  get { return state; } }

        /// <summary>
        /// 执行报文
        /// </summary>
        public string? LastMessage {  get { return lastmessage; } }

        private Mitsubishi() 
        {
            plc = new ActUtlType64();
            
            plc.ActLogicalStationNumber = 1;
            plc.ActPassword = "";
            lastmessage = string.Empty;
            isopen = false;
        }

        /// <summary>
        /// 设定逻辑站号和密码
        /// </summary>
        /// <param name="LogicalStationNumber"></param>
        /// <param name="Password"></param>
        public void Set(int LogicalStationNumber,string Password)
        {
            plc.ActLogicalStationNumber = LogicalStationNumber;
            plc.ActPassword = Password;
        }

        public static Mitsubishi Instance
        {
            get { return instance; }
        }

        public ActUtlType64 plc;

        /// <summary>
        /// 关闭链接
        /// </summary>
        public void Close()
        {
            lock(this)
            {
                try
                {
                    int iRet = plc.Close();
                    if(iRet == 0)
                    {
                        state = true;
                        lastmessage = "关闭成功";
                        isopen = false;

                    }
                    else
                    {
                        state = false;
                        lastmessage = "关闭失败"+GetErrInfo((uint)iRet);
                    }
                }
                catch (Exception e)
                {
                    state = false;
                    lastmessage = "关闭时出错"+e.Message;
                }
            }
        }

        public bool Open()
        {
            lock (this)
            {
                try
                {
                    if(IsOpen)
                    {
                        return true;
                    }
                    int iRet = plc.Open();
                    if (iRet == 0)
                    {
                        lastmessage = "PLC打开成功。";
                        isopen = true;
                        state = true;
                        return true;
                    }
                    else
                    {
                        state = false;
                        lastmessage = "PLC打开失败" + GetErrInfo((uint)iRet);
                        isopen = false;
                        return false;
                    }
                    
                }
                catch (Exception e)
                {
                    state=false;
                    lastmessage = "PLC打开时出错"+e.Message;
                    isopen=false;
                    return false;
                }
            }
        }

        public bool ReadM(uint addr)
        {
            lock (this)
            {
                try
                {
                    int data;
                    int iResult = plc.GetDevice("M" + addr.ToString(), out data);
                    if(iResult == 0)
                    {
                        state = true;
                        if (data == 0)
                            return false;
                        else
                            return false;
                    }
                    else
                    {
                        state = false;

                        lastmessage = "M寄存器读取失败，" + GetErrInfo((uint)iResult);
                        return false;
                    }
                }
                catch(Exception e)
                {
                    state = false;

                    lastmessage = "M寄存器读取时出错，" + e.Message;
                    return false;
                }
            }
        }

        public void WriteM(uint addr)
        {
            lock (this)
            {

            }
        }

        string GetErrInfo(uint errCode)
        {
            switch (errCode)
            {
                case 0x0:return "Success";
                case 0x01010002:return "超时错误";
                case 0x01010005:return "传文错误";
                case 0x01010010:return "PC No.错误，在指定的站号中无法进行通讯";
                case 0x01010011:return "模式错误，是不支持的指令";
                case 0x01010012:return "特殊模块指定错误";
                default:return "未知错误" + errCode.ToString();
            }
        }
    }
}